package com.travel.server.manager.impl.dal;

import com.travel.common.CommonConstant;
import com.travel.common.exception.WorkCode;
import com.travel.common.exception.WorkException;
import com.travel.common.util.CollectionUtil;
import com.travel.server.manager.dao.ProjectInfoDao;
import com.travel.server.manager.impl.enums.OrderStepEnum;
import com.travel.server.manager.model.*;
import com.travel.server.manager.model.dto.ProjectEnumDto;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @Author: LiZhenhui
 * @Date: 2018/10/26 18:26
 * @Desc:
 */
@Component
@Slf4j
public class ProjectDal {

    @Autowired
    private ProjectInfoDao projectInfoDao;

    @Autowired
    private OrderDal orderDal;

    private final static List<String> ORDER_STEP_LIST = Arrays.asList(OrderStepEnum.APPLY_WAIT.getStep(),OrderStepEnum.DATA_WAIT_EXAM.getStep(),OrderStepEnum.ING.getStep(),
            OrderStepEnum.DATA_WAIT_SUBMIT.getStep(), OrderStepEnum.ORDER_REFUND.getStep(), OrderStepEnum.ORDER_WAIT.getStep(), OrderStepEnum.QUESTION_WAIT_EXAM.getStep(),
            OrderStepEnum.QUESTION_WAIT_SUBMIT.getStep(), OrderStepEnum.PROJECT_WAIT.getStep(), OrderStepEnum.WAIT_CONTRACT.getStep());

    @Autowired
    private SpecialDal specialDal;

    public PageDto<ProjectInfo> select(ProjectParam param){
        ProjectInfoExample example = makeExample(param);
        int total = projectInfoDao.countByExample(example);
        example.setOrderByClause("update_time desc");
        List<ProjectInfo> list = projectInfoDao.selectByExample(example);

        PageDto<ProjectInfo> pageDto = new PageDto<>();
        pageDto.setTotal(total);
        pageDto.setList(list);

        return pageDto;
    }

    public ProjectInfo selectById(Integer id){
        ProjectInfo projectInfo = projectInfoDao.selectByPrimaryKey(id);
        if(projectInfo == null){
            log.info("未查询到项目信息, id {}", id);
            throw new WorkException(WorkCode.RECORD_NOT_EXIST);
        }
        return projectInfo;
    }

    public boolean hasUnCompleteOrder(List<Integer> projectIdList){
        SpecialDal.SpecialParam specialParam = new SpecialDal.SpecialParam();
        specialParam.setProjectIdList(projectIdList);
        List<ProjectSpecial> specialList = specialDal.selectByExample(specialParam);
        if(CollectionUtil.isEmpty(specialList)){
            return false;
        }
        List<Integer> specialIdList = new ArrayList<>();
        for(ProjectSpecial special : specialList){
            specialIdList.add(special.getId());
        }

        OrderDal.OrderInfoParam orderParam = new OrderDal.OrderInfoParam();
        orderParam.setSpecialIdList(specialIdList);
        orderParam.setStepList(ORDER_STEP_LIST);
        List<OrderInfo> orderList = orderDal.selectByExample(orderParam);
        if(CollectionUtil.isEmpty(orderList)){
            return false;
        }
        return true;
    }

    public List<ProjectInfo> selectByExample(ProjectParam param){
        ProjectInfoExample example = makeExample(param);
        return projectInfoDao.selectByExample(example);
    }
    public Integer selectUsefulTotal(){
        ProjectParam param = new ProjectParam();
        ProjectInfoExample example = makeExample(param);
        return projectInfoDao.countByExample(example);
    }


    public List<String> selectEnum(ProjectEnumDto dto){
        return projectInfoDao.selectEnum(dto);
    }

    public Map<Integer, String> makeProjectName(List<ProjectSpecial> list){
        Map<Integer, String> map = new HashMap<>();
        List<Integer> idList = new ArrayList<>();
        for(ProjectSpecial special : list){
            idList.add(special.getProjectId());
        }
        ProjectDal.ProjectParam param = new ProjectDal.ProjectParam();
        param.setIdList(idList);
        List<ProjectInfo> projectList = selectByExample(param);
        if(!CollectionUtil.isEmpty(projectList)){
            for(ProjectInfo projectInfo : projectList){
                map.put(projectInfo.getId(), projectInfo.getName());
            }
        }
        return map;
    }

    public ProjectInfoExample makeExample(ProjectParam param){
        ProjectInfoExample example = new ProjectInfoExample();
        ProjectInfoExample.Criteria criteria = example.or();
        if(StringUtils.isNotBlank(param.getName())){
            criteria.andNameLike("%" + param.getName() + "%");
        }
        if(StringUtils.isNotBlank(param.getRealName())){
            criteria.andNameEqualTo(param.getRealName());
        }
        if(StringUtils.isNotBlank(param.getType())){
            criteria.andProjectTypeEqualTo(param.getType());
        }
        if(StringUtils.isNotBlank(param.getCountry())){
            criteria.andCountryEqualTo(param.getCountry());
        }
        if(!CollectionUtil.isEmpty(param.getIdList())){
            criteria.andIdIn(param.getIdList());
        }
        if(param.getState() != null){
            criteria.andStateEqualTo(param.getState());
        }
        if(StringUtils.isNotBlank(param.getProjectGroup())){
            criteria.andProjectGroupLike("%" + param.getProjectGroup() + "%");
        }
        if(param.getStartPrice() != null){
            criteria.andPriceGreaterThanOrEqualTo(param.getStartPrice());
        }
        if(param.getEndPrice() != null){
            criteria.andPriceLessThanOrEqualTo(param.getEndPrice());
        }
        if(param.getStock() != null){
            criteria.andStockEqualTo(param.getStock());
        }
        if(param.getOffset() != null && param.getLimit() != null){
            example.setOffset(param.getOffset());
            example.setLimit(param.getLimit());
        }
        return example;
    }

    public void insertOrUpdate(ProjectInfo projectInfo){
        if(projectInfo.getId() != null){
            projectInfoDao.updateByPrimaryKey(projectInfo);
        }else{
            projectInfoDao.insertSelective(projectInfo);
        }
    }

    public int updateProjectType(String oldProjectType, String newProjectType){
        return projectInfoDao.updateProjectType(oldProjectType, newProjectType);
    }

    public int updateProject(String oldProject, String newProject){
        return projectInfoDao.updateProject(oldProject, newProject);
    }

    public Integer selectOrderChargeCount(){
        return projectInfoDao.selectOrderChargeCount();
    }

    public ProjectInfo selectByNumber(String number){
        ProjectInfoExample example = new ProjectInfoExample();
        ProjectInfoExample.Criteria criteria = example.or();
        criteria.andNumberEqualTo(number);
        example.setOrderByClause("state desc");
        return CollectionUtil.getFirst(projectInfoDao.selectByExample(example));
    }

    public ProjectInfo getProjectInfo(Integer id, UserInfo userInfo){
        ProjectInfo projectInfo;
        if(id != null) {
            projectInfo = selectById(id);
        }else{
            projectInfo = new ProjectInfo();
            projectInfo.setState(CommonConstant.YES);
            projectInfo.setCreateBy(userInfo.getName());
            projectInfo.setCreateTime(new Date());
        }
        return projectInfo;
    }

    @Data
    public static class ProjectParam{
        private String name;

        private String realName;

        private String type;

        private String country;

        private List<Integer> idList;

        private String projectGroup;

        private Integer offset;

        private Integer limit;

        private Long startPrice;

        private Long endPrice;

        private Integer stock;

        private Integer state = 1;
    }
}
